package com.ruoyi.order.service.impl;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.aliyun.AlipayConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisUtil;
import com.ruoyi.common.utils.OrderNumberGeneratorUtil;
import com.ruoyi.common.utils.ProjectConstant;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.aliyun.ThroughUtil;
import com.ruoyi.common.utils.date.DateUtils;
import com.ruoyi.common.wx.WxConfig;
import com.ruoyi.framework.security.auth.JWTUser;
import com.ruoyi.framework.security.auth.RequestContext;
import com.ruoyi.order.appStoreUtil.AppStoreUtil;
import com.ruoyi.order.domain.AppStoreNotifyPayLoadDto;
import com.ruoyi.order.domain.OrderComplaint;
import com.ruoyi.order.domain.OrderEvaluate;
import com.ruoyi.order.domain.OrderInfo;
import com.ruoyi.order.domain.UserAppleRefund;
import com.ruoyi.order.mapper.OrderComplaintMapper;
import com.ruoyi.order.mapper.OrderEvaluateMapper;
import com.ruoyi.order.mapper.OrderInfoMapper;
import com.ruoyi.order.mapper.UserAppleRefundMapper;
import com.ruoyi.order.pojo.AppConsumeDTO;
import com.ruoyi.order.pojo.AppMyOrderDTO;
import com.ruoyi.order.pojo.AppProjectDTO;
import com.ruoyi.order.pojo.AppWithdrawalDTO;
import com.ruoyi.order.service.AppOrderService;
import com.ruoyi.system.domain.PriceSetting;
import com.ruoyi.system.domain.UserSystemMsg;
import com.ruoyi.system.mapper.UserSystemMsgMapper;
import com.ruoyi.system.service.IPriceSettingService;
import com.ruoyi.thread.TaskAsync;
import com.ruoyi.user.domain.User;
import com.ruoyi.user.domain.UserCapitalFlow;
import com.ruoyi.user.domain.UserTotalCapital;
import com.ruoyi.user.mapper.UserCapitalFlowMapper;
import com.ruoyi.user.mapper.UserMapper;
import com.ruoyi.user.service.IUserTotalCapitalService;

@Service
public class AppOrderServiceImpl implements AppOrderService {

	@Autowired
	private IPriceSettingService priceSettingService;
	@Autowired
	private OrderInfoMapper orderInfoMapper;
	@Autowired
	private WxConfig wxConfig;
	@Autowired
	private AlipayConfig alipayConfig;
	@Autowired
	private UserCapitalFlowMapper userCapitalFlowMapper;
	@Autowired
	private TaskAsync taskAsync;
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private OrderComplaintMapper orderComplaintMapper;
	@Autowired
	private OrderEvaluateMapper orderEvaluateMapper;
	@Autowired
	private IUserTotalCapitalService userTotalCapitalService;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private UserSystemMsgMapper userSystemMsgMapper;


	/**
	 * 	获取用户ID
	 * @return
	 */
	private Long getLoginUserId() {
		Object object = RequestContext.get("userInfo");
		if(null == object) {
			return null;
		}
		JWTUser jwtUser = (JWTUser) object;
		if(null == jwtUser || null == jwtUser.getId()) {
			return null;
		}
		return jwtUser.getId();
	}

	@Override
	public AjaxResult getOrder(Integer payType, Long businessId, BigDecimal money, Integer type,String orderNo,String dynamicIds,
			Long couponId,Long toUserId,HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, userId).select(User::getId,User::getSex,User::getRegisterTime));
			if(null == user) {
				return AjaxResult.error(50010,"请重新登录");
			}
			if("F".equals(user.getSex())) {
				String format = DateUtils.format(user.getRegisterTime(), "yyyyMMdd");
				if(Integer.valueOf(format) >= 20240906) {
					return AjaxResult.error("当前账号不支持开通会员");
				}
			}
			OrderInfo orderInfo = new OrderInfo();
			// 存在订单直接付款
			if(StringUtils.isNotEmpty(orderNo)) {
				orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
				if(null == orderInfo) {
					return AjaxResult.error("订单不存在");
				}
				if(!"0".equals(orderInfo.getOrderStatus())) {
					return AjaxResult.error("订单状态有误,请刷新");
				}
				//				if(!"1".equals(orderInfo.getPayType()) && !"2".equals(orderInfo.getPayType())) {
				//					return AjaxResult.error("未知支付方式");
				//				}
				orderInfo.setPayType(String.valueOf(payType));
			}else {
				String remark = "充值余额";
				String orderType = String.valueOf(ProjectConstant.BusinessType.CURRENCY);
				if(1 == type) {
					remark = "充值VIP";
					orderType = String.valueOf(ProjectConstant.BusinessType.VIP);
					PriceSetting one = priceSettingService.getById(businessId);
					if(null != one ) {
						money = one.getCurrentPrice();
					}
				}else if(6 == type) {
					PriceSetting one = priceSettingService.getById(businessId);
					if(null != one ) {
						money = one.getCurrentPrice();
					}
					// 保存优惠券ID
					if(null != couponId) {
						orderInfo.setCouponId(couponId);
					}
				}
				// 保存对方ID 用于分佣
				if(null != toUserId && toUserId > 0) {
					orderInfo.setToUserId(toUserId);
				}
				orderInfo.setOrderType(orderType);
				//订单备注
				orderInfo.setRemark(remark);
				// 订单号
				orderInfo.setOrderNo(OrderNumberGeneratorUtil.get());
				// 创建时间
				orderInfo.setCreateTime(new Date());
				// 支付用户ID
				orderInfo.setPayUserId(userId);
				// 未支付
				orderInfo.setOrderStatus("0");
				// 订单时间
				orderInfo.setOrderCreateTime(new Date());
				// 订单支付类型
				orderInfo.setPayType(String.valueOf(payType));
				//设置订单金额
				orderInfo.setOrderAmount(money);
				//设置订单业务ID
				orderInfo.setRelatedId(businessId);
				if(3 == payType) { // 余额 支付
					// 已支付
//					orderInfo.setOrderStatus("1");
//					// 校验余额
//					boolean checkUserAmount = userTotalCapitalService.checkUserAmount("3", userId, money);
//					if(!checkUserAmount) {
//						return AjaxResult.error("余额不足请先充值");
//					}
//					// 减少余额
//					userTotalCapitalService.initUserTotalCapital("3", userId, money, 0);
//					// 保存订单信息
//					orderInfoMapper.insert(orderInfo);
					return AjaxResult.success("支付成功");
				}else {
					// 支付过期时间
					//orderInfo.setPayExpireTime(DateUtils.addMinute(new Date(), 15));
					// 保存订单信息
					orderInfoMapper.insert(orderInfo);
//					if(2 == type) { // 活动支付才有支付过期
//						// 添加订单过期定时任务
//						taskAsync.addOrderTask(orderInfo.getRelatedId(), orderInfo.getOrderNo(), userId, orderInfo.getPayExpireTime(), 1);
//					}
				}
			}
			if("1".equals(orderInfo.getPayType())) {//String.valueOf(money)
				return createWxPayOrder(orderInfo.getOrderNo(), String.valueOf(money), orderInfo.getRemark(), "APP");

			}else if("2".equals(orderInfo.getPayType())) {
				return createAliPayOrder(orderInfo.getOrderNo(), String.valueOf(money), orderInfo.getRemark());
			}
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络繁忙");
		}
		return AjaxResult.error("参数异常");
	}

	/**
	 *  微信支付
	 * @param orderNo
	 * @param amount
	 * @param remark
	 * @param tradeType
	 * @return
	 */
	private AjaxResult createWxPayOrder(String orderNo, String amount, String remark, String tradeType) {
		try {
			WXPay wxpay = new WXPay(wxConfig);
			Map<String, String> data = new HashMap<>();
			//微信开放平台审核通过的应用APPID（请登录open.weixin.qq.com查看，注意与公众号的APPID不同）
			data.put("appid", wxConfig.getAppID());
			//微信支付分配的商户号
			data.put("mch_id", wxConfig.getMchID());
			//            data.put("mch_id", wxConfig.getMchID());
			//data.put("openid", openId);
			//随机字符串，不长于32位
			data.put("nonce_str", WXPayUtil.generateNonceStr());
			//APP——需传入应用市场上的APP名字-实际商品名称，天天爱消除-游戏充值。
			data.put("body", "蜜搭APP");
			//商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一
			data.put("out_trade_no", orderNo);
			//订单总金额，单位为分
			data.put("total_fee", ThroughUtil.castToCent(amount));
			//自己的服务器IP地址
			data.put("spbill_create_ip", InetAddress.getLocalHost().getHostAddress());
			//异步通知地址（请注意必须是外网）
			data.put("notify_url", wxConfig.getNotifyUrl());
			//交易类型
			data.put("trade_type", tradeType);
			//附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
			data.put("attach", "");
			data.put("sign", WXPayUtil.generateSignature(data, wxConfig.getKey(),
					WXPayConstants.SignType.MD5));
			//使用官方API请求预付订单
			Map<String, String> response = wxpay.unifiedOrder(data);
			if ("SUCCESS".equals(response.get("return_code"))) {//主要返回以下5个参数
				Map<String, String> param = new HashMap<>();
				param.put("appid", wxConfig.getAppID());
				param.put("partnerid", response.get("mch_id"));
				param.put("prepayid", response.get("prepay_id"));
				param.put("package", "Sign=WXPay");
				param.put("noncestr", WXPayUtil.generateNonceStr());
				param.put("timestamp", System.currentTimeMillis() / 1000 + "");
				param.put("sign", WXPayUtil.generateSignature(param, wxConfig.getKey(),
						WXPayConstants.SignType.MD5));
				return AjaxResult.success("成功",JSON.toJSONString(param));
			} else {
				return AjaxResult.success("失败",response.get("return_msg"));
			}
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.success("下单失败");
		}
	}

	/**
	 * 	支付宝支付
	 * @param orderNo
	 * @param amount
	 * @param remark
	 * @return
	 */
	private AjaxResult createAliPayOrder(String orderNo, String amount, String remark) {
		//构造client
		CertAlipayRequest certAlipayRequest = new CertAlipayRequest ();

		//设置网关地址
		certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
		//设置应用Id
		certAlipayRequest.setAppId(alipayConfig.getAppId());
		//设置应用私钥
		certAlipayRequest.setPrivateKey(alipayConfig.getAppPrivateKey());
		//设置请求格式，固定值json
		certAlipayRequest.setFormat("json");	
		//设置字符集
		certAlipayRequest.setCharset("UTF-8");
		//设置签名类型
		certAlipayRequest.setSignType("RSA2");
		//设置应用公钥证书路径
		certAlipayRequest.setCertPath(alipayConfig.getAppCertPublicKey());
		//设置支付宝公钥证书路径
		certAlipayRequest.setAlipayPublicCertPath(alipayConfig.getAlipayCertPublicKeyRSA2());
		//设置支付宝根证书路径
		certAlipayRequest.setRootCertPath(alipayConfig.getAlipayRootCert());
		//构造client
		AlipayClient alipayClient = null;
		try {
			alipayClient = new DefaultAlipayClient(certAlipayRequest);
		} catch (AlipayApiException e1) {
			e1.printStackTrace();
		}
		//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setSubject(remark);
		model.setBody(remark);
		model.setOutTradeNo(orderNo);
		model.setTotalAmount(amount);
		model.setTimeoutExpress("1c");
		model.setProductCode("QUICK_MSECURITY_PAY");
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest appPayRequest = new AlipayTradeAppPayRequest();
		appPayRequest.setBizModel(model);
		appPayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());// 回调地址
		try {
			AlipayTradeAppPayResponse appPayResponse = alipayClient.sdkExecute(appPayRequest);
			String body = appPayResponse.getBody();
			System.out.println("支付宝返回值：");
			System.out.println(body);
			return AjaxResult.success("成功",body);	
		} catch (Exception e) {
			return AjaxResult.error(e.getMessage());
		}
	}

	@Override
	public AjaxResult withdrawalRecord(Integer pageNo, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			pageNo = (pageNo -1)*10;
			List<AppWithdrawalDTO> list = userCapitalFlowMapper.withdrawalRecord(userId, pageNo);
			list.parallelStream().forEach(withdrawal ->{
				withdrawal.setTitle("提现至支付宝");
				if(1 == withdrawal.getSource()) {
					withdrawal.setTitle("提现至微信");
				}
			});
			return AjaxResult.success(list);
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult rechargeRecord(Integer pageNo, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			//pageNo = (pageNo -1)*10;
			IPage<AppConsumeDTO> consumeRecord = userCapitalFlowMapper.consumeRecord(new Page<AppConsumeDTO>().setCurrent(pageNo).setSize(10),userId, 1);
			return AjaxResult.success(consumeRecord.getRecords());
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult vipBuyRecord(Integer pageNo, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			//pageNo = (pageNo -1)*10;
			IPage<AppConsumeDTO> consumeRecord = userCapitalFlowMapper.consumeRecord(new Page<AppConsumeDTO>().setCurrent(pageNo).setSize(10),userId, 2);
			return AjaxResult.success(consumeRecord.getRecords());
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult getOrderList(Integer orderStatus, Integer pageNo, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			//pageNo = (pageNo -1)*10;

			IPage<AppMyOrderDTO> orderList = orderInfoMapper.getOrderList(new Page<AppMyOrderDTO>().setCurrent(pageNo).setSize(10), orderStatus, userId);
			orderList.getRecords().parallelStream().forEach(order ->{
				if(null != order.getAmount()) {
					order.setAmount(new BigDecimal(order.getAmount().stripTrailingZeros().toPlainString()));
				}
				// 转换为秒
				order.setPayExpireTime(DateUtils.getDaySecond(new Date(), order.getTime()));
			});
			return AjaxResult.success(orderList.getRecords());
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult cancelOrder(String orderNo, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderStatus, 0).eq(OrderInfo::getOrderNo, orderNo)
					.select(OrderInfo::getId,OrderInfo::getPayUserId));
			if(null == orderInfo) {
				return AjaxResult.error("订单不存在");
			}
			if(userId.longValue() != orderInfo.getPayUserId().longValue()) {
				return AjaxResult.error("不可操作TA人订单");
			}
			orderInfo.setOrderStatus("4");
			orderInfo.setExtend("订单取消,时间:"+DateUtils.dateToString(new Date(),"yyyy-MM-dd HH:mm:ss"));
			orderInfoMapper.updateById(orderInfo);
			return AjaxResult.success();
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult reminderOrder(String orderNo, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderStatus, 1).eq(OrderInfo::getOrderNo, orderNo)
					.select(OrderInfo::getId,OrderInfo::getPayUserId));
			if(null == orderInfo) {
				return AjaxResult.error("订单不存在");
			}
			if(userId.longValue() != orderInfo.getPayUserId().longValue()) {
				return AjaxResult.error("不可催促TA人订单");
			}
			// 2分钟 防止重复催单
			if(!redisUtil.setIfAbsentCustom("reminderOrder:"+orderNo,120000)) {
				return AjaxResult.error("已催单,请耐心等待~");
			}
			// 推送消息
			taskAsync.sendSystemMsg(orderInfo.getPayUserId(), userId, 1,"","");
			return AjaxResult.success();
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult orderComplaint(AppMyOrderDTO order, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			// orderComplaintMapper
			OrderComplaint orderComplaint = new OrderComplaint();
			orderComplaint.setUserId(userId);
			orderComplaint.setContent(order.getContent());
			if(StringUtils.isNotEmpty(order.getOrderNo())) { // 订单投诉
				OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderStatus, 1).eq(OrderInfo::getOrderNo, order.getOrderNo())
						.select(OrderInfo::getId,OrderInfo::getPayUserId));
				if(null == orderInfo) {
					return AjaxResult.error("订单不存在");
				}
				if(userId.longValue() != orderInfo.getPayUserId().longValue()) {
					return AjaxResult.error("不可投诉TA人订单");
				}
				orderComplaint.setType(1);
				orderComplaint.setBusinessId(orderInfo.getId());
			}else { // 普通投诉
				orderComplaint.setType(2);	
			}
			orderComplaintMapper.insert(orderComplaint);
			return AjaxResult.success();
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult orderEvaluate(OrderEvaluate order, HttpServletRequest request) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderStatus, 1).eq(OrderInfo::getOrderNo, order.getOrderNo())
					.select(OrderInfo::getId,OrderInfo::getActualAmount,OrderInfo::getToUserId,OrderInfo::getPayUserId));
			if(null == orderInfo) {
				return AjaxResult.error("订单不存在");
			}
			if(userId.longValue() != orderInfo.getPayUserId().longValue()) {
				return AjaxResult.error("不可评价TA人订单");
			}
			order.setToUserId(orderInfo.getToUserId());
			order.setUserId(userId);
			order.setBusinessId(orderInfo.getId());
			order.setAmount(orderInfo.getActualAmount().stripTrailingZeros().toPlainString());
			orderEvaluateMapper.insert(order);
			return AjaxResult.success();
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	@Transactional
	public AjaxResult buyVip(Long businessId, HttpServletRequest request) {
		Long userId = getLoginUserId();
		if(null == userId) {
			return AjaxResult.error(50010,"请重新登录");
		}
		PriceSetting one = priceSettingService.getById(businessId);
		if(null == one ) {
			return AjaxResult.error("VIP规格选择有误,请重新选择");
		}
		User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, userId).select(User::getId,User::getVip,User::getVipExpireTime));
		if(null == user) {
			return AjaxResult.error(50010,"请重新登录");
		}
		// 校验余额
		UserTotalCapital totalCapital = userTotalCapitalService.getOne(new LambdaQueryWrapper<UserTotalCapital>().eq(UserTotalCapital::getUserId, userId).eq(UserTotalCapital::getAmountType, 3));
		if(null == totalCapital) {
			return AjaxResult.error("余额不足");
		}
		BigDecimal totalAmount = totalCapital.getTotalAmount().subtract(totalCapital.getFrozenAmount());
		if(totalAmount.compareTo(one.getCurrentPrice()) == -1) {
			return AjaxResult.error("余额不足");
		}
		userTotalCapitalService.initUserTotalCapital("3", userId, one.getCurrentPrice(), 0);
		if(null == user.getVipExpireTime() || com.ruoyi.common.utils.date.DateUtils.isOverdue(new Date(), user.getVipExpireTime())) {
			Calendar curr = Calendar.getInstance();
			curr.setTime(new Date());
			curr.set(Calendar.MONTH,curr.get(Calendar.MONTH)+Integer.valueOf(one.getPayCode()));
			user.setVip(1);
			user.setVipExpireTime(curr.getTime());
		}else {
			//续费VIP
			Calendar curr = Calendar.getInstance();
			if(user.getVipExpireTime().before(new Date())) {
				curr.setTime(new Date());
			}else {
				curr.setTime(user.getVipExpireTime());
			}
			curr.set(Calendar.MONTH,curr.get(Calendar.MONTH)+Integer.valueOf(one.getPayCode()));
			user.setVip(1);
			user.setVipExpireTime(curr.getTime());
		}
		userMapper.updateById(user);
		UserCapitalFlow userCapitalFlow = new UserCapitalFlow();
		userCapitalFlow.setType(5);
		userCapitalFlow.setBusinessType(1);
		userCapitalFlow.setAmount(one.getCurrentPrice());
		userCapitalFlow.setUserId(userId);
		userCapitalFlow.setToUserId(0L);
		userCapitalFlow.setOrderNo(OrderNumberGeneratorUtil.get());
		userCapitalFlow.setRemark("VIP充值");
		userCapitalFlow.setSource(0);
		userCapitalFlow.setRelatedId(one.getId());
		userCapitalFlow.setIsSettle(1);
		userCapitalFlow.setNameType(one.getPriceName());
		userCapitalFlowMapper.insert(userCapitalFlow);
		return AjaxResult.success();
	}

	@Override
	@Transactional
	public AjaxResult projectOperate(AppProjectDTO project) {
		Long userId = getLoginUserId();
		if(null == userId) {
			return AjaxResult.error(50010,"请重新登录");
		}
		UserSystemMsg userSystemMsg = userSystemMsgMapper.selectOne(new LambdaQueryWrapper<UserSystemMsg>().eq(UserSystemMsg::getOrderNo, project.getOrderNo())
				.eq(UserSystemMsg::getUserId, userId));
		if(null == userSystemMsg) {
			return AjaxResult.error("参数有误");
		}
		if(3 == userSystemMsg.getOrderStatus()) {
			return AjaxResult.error("此咨询项目服务已结束");
		}else if(2 == userSystemMsg.getOrderStatus()) {
			return AjaxResult.error("此咨询项目服务已拒绝");
		}
		OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, project.getOrderNo())
				.eq(OrderInfo::getToUserId, userId).select(OrderInfo::getId,OrderInfo::getOrderStatus,OrderInfo::getOrderAmount,OrderInfo::getRemark
						,OrderInfo::getToUserId,OrderInfo::getPayType));
		if(null == orderInfo) {
			return AjaxResult.error("参数有误");
		}

		userSystemMsg.setOrderStatus(project.getType());
		switch (project.getType()) {
		// orderInfo : 0=未支付，1=已支付，3=已同意，4=已拒绝，5=已完成
		case 1:
			orderInfo.setOrderStatus("3");
			orderInfoMapper.updateById(orderInfo);
			userSystemMsgMapper.updateById(userSystemMsg);
			break;
		case 2:
			// 拒绝 退款
			// 添加余额
			userTotalCapitalService.initUserTotalCapital("3", userId, orderInfo.getOrderAmount(), 1);
			orderInfo.setOrderStatus("4");
			orderInfoMapper.updateById(orderInfo);
			userSystemMsgMapper.updateById(userSystemMsg);
			break;
		case 3:
			orderInfo.setOrderStatus("5");
			orderInfoMapper.updateById(orderInfo);
			userSystemMsgMapper.updateById(userSystemMsg);
			BigDecimal money = priceSettingService.qryScale("consultProportion", orderInfo.getOrderAmount());
			if("3".equals(orderInfo.getPayType())) {
				orderInfo.setPayType("0");
			}
			// 增加余额
			userTotalCapitalService.initUserTotalCapital("1", orderInfo.getToUserId(), money, 1);
			taskAsync.addOrderMsg(orderInfo.getPayUserId(),orderInfo.getToUserId(), 4, orderInfo.getRemark(),orderInfo.getOrderAmount(),money,Integer.valueOf(orderInfo.getPayType()));
			break;
		default:
			break;
		}
		return AjaxResult.success();
	}

	@Override
	public AjaxResult getIncomeRecord(Integer pageNo) {
		try {
			Long userId = getLoginUserId();
			if(null == userId) {
				return AjaxResult.error(50010,"请重新登录");
			}
			// 9=活动支付、10=单次咨询支付、3=打赏咨询师、6=礼物收入、8=语音通话收益
			List<Integer> types = new ArrayList<Integer>();
			types.add(3);types.add(6);types.add(8);types.add(9);types.add(10);
			Page<UserCapitalFlow> page = userCapitalFlowMapper.selectPage(new Page<UserCapitalFlow>().setCurrent(pageNo).setSize(10), new LambdaQueryWrapper<UserCapitalFlow>()
					.eq(UserCapitalFlow::getUserId, userId).eq(UserCapitalFlow::getType, 4).in(UserCapitalFlow::getBusinessType, types)
					.orderByDesc(UserCapitalFlow::getCreateTime));
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("total",page.getTotal());
			map.put("list", page.getRecords());
			return AjaxResult.success(map);
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络开小差啦");
		}
	}

	@Override
	public AjaxResult getConsumeRecord(Integer pageNo) {
		Long userId = getLoginUserId();
		if(null == userId) {
			return AjaxResult.error(50010,"请重新登录");
		}
		try {
			// 1=充值VIP 5=赠送礼物 7=语音通话支付 9=有人报名活动 10=有人下单咨询项目
			List<Integer> types = new ArrayList<Integer>();
			types.add(3);types.add(6);types.add(8);types.add(9);types.add(10);
			Page<UserCapitalFlow> page = userCapitalFlowMapper.selectPage(new Page<UserCapitalFlow>().setCurrent(pageNo).setSize(10), new LambdaQueryWrapper<UserCapitalFlow>()
					.eq(UserCapitalFlow::getUserId, userId).eq(UserCapitalFlow::getType, 5).in(UserCapitalFlow::getBusinessType, types)
					.orderByDesc(UserCapitalFlow::getCreateTime));
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("total",page.getTotal());
			map.put("list", page.getRecords());
			return AjaxResult.success(map);
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error("网络繁忙");
		}
	}

	@Autowired
	private UserAppleRefundMapper userAppleRefundMapper;
	
	@Override
	public String appStoreMsgNotify(AppStoreNotifyPayLoadDto appStoreNotifyPayLoadDto) {
		UserAppleRefund refund = new UserAppleRefund();
		
		refund.setSignData(appStoreNotifyPayLoadDto.getSignedPayload());
		try {
			/**
			 * {"data":{"environment":"Production","bundleVersion":"112","bundleId":"app.mida.com",
			 * "signedTransactionInfo":"eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQWdJUWZUbGZkMGZOdkZXdnpDMVlJQU5zWGpBS0JnZ3Foa2pPUFFRREF6QjFNVVF3UWdZRFZRUURERHRCY0hCc1pTQlhiM0pzWkhkcFpHVWdSR1YyWld4dmNHVnlJRkpsYkdGMGFXOXVjeUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURUxNQWtHQTFVRUN3d0NSell4RXpBUkJnTlZCQW9NQ2tGd2NHeGxJRWx1WXk0eEN6QUpCZ05WQkFZVEFsVlRNQjRYRFRJek1Ea3hNakU1TlRFMU0xb1hEVEkxTVRBeE1URTVOVEUxTWxvd2daSXhRREErQmdOVkJBTU1OMUJ5YjJRZ1JVTkRJRTFoWXlCQmNIQWdVM1J2Y21VZ1lXNWtJR2xVZFc1bGN5QlRkRzl5WlNCU1pXTmxhWEIwSUZOcFoyNXBibWN4TERBcUJnTlZCQXNNSTBGd2NHeGxJRmR2Y214a2QybGtaU0JFWlhabGJHOXdaWElnVW1Wc1lYUnBiMjV6TVJNd0VRWURWUVFLREFwQmNIQnNaU0JKYm1NdU1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCRUZFWWUvSnFUcXlRdi9kdFhrYXVESENTY1YxMjlGWVJWLzB4aUIyNG5DUWt6UWYzYXNISk9OUjVyMFJBMGFMdko0MzJoeTFTWk1vdXZ5ZnBtMjZqWFNqZ2dJSU1JSUNCREFNQmdOVkhSTUJBZjhFQWpBQU1COEdBMVVkSXdRWU1CYUFGRDh2bENOUjAxREptaWc5N2JCODVjK2xrR0taTUhBR0NDc0dBUVVGQndFQkJHUXdZakF0QmdnckJnRUZCUWN3QW9ZaGFIUjBjRG92TDJObGNuUnpMbUZ3Y0d4bExtTnZiUzkzZDJSeVp6WXVaR1Z5TURFR0NDc0dBUVVGQnpBQmhpVm9kSFJ3T2k4dmIyTnpjQzVoY0hCc1pTNWpiMjB2YjJOemNEQXpMWGQzWkhKbk5qQXlNSUlCSGdZRFZSMGdCSUlCRlRDQ0FSRXdnZ0VOQmdvcWhraUc5Mk5rQlFZQk1JSCtNSUhEQmdnckJnRUZCUWNDQWpDQnRneUJzMUpsYkdsaGJtTmxJRzl1SUhSb2FYTWdZMlZ5ZEdsbWFXTmhkR1VnWW5rZ1lXNTVJSEJoY25SNUlHRnpjM1Z0WlhNZ1lXTmpaWEIwWVc1alpTQnZaaUIwYUdVZ2RHaGxiaUJoY0hCc2FXTmhZbXhsSUhOMFlXNWtZWEprSUhSbGNtMXpJR0Z1WkNCamIyNWthWFJwYjI1eklHOW1JSFZ6WlN3Z1kyVnlkR2xtYVdOaGRHVWdjRzlzYVdONUlHRnVaQ0JqWlhKMGFXWnBZMkYwYVc5dUlIQnlZV04wYVdObElITjBZWFJsYldWdWRITXVNRFlHQ0NzR0FRVUZCd0lCRmlwb2RIUndPaTh2ZDNkM0xtRndjR3hsTG1OdmJTOWpaWEowYVdacFkyRjBaV0YxZEdodmNtbDBlUzh3SFFZRFZSME9CQllFRkFNczhQanM2VmhXR1FsekUyWk9FK0dYNE9vL01BNEdBMVVkRHdFQi93UUVBd0lIZ0RBUUJnb3Foa2lHOTJOa0Jnc0JCQUlGQURBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpFQTh5Uk5kc2twNTA2REZkUExnaExMSndBdjVKOGhCR0xhSThERXhkY1BYK2FCS2pqTzhlVW85S3BmcGNOWVVZNVlBakFQWG1NWEVaTCtRMDJhZHJtbXNoTnh6M05uS20rb3VRd1U3dkJUbjBMdmxNN3ZwczJZc2xWVGFtUllMNGFTczVrPSIsIk1JSURGakNDQXB5Z0F3SUJBZ0lVSXNHaFJ3cDBjMm52VTRZU3ljYWZQVGp6Yk5jd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVUVBd3dTUVhCd2JHVWdVbTl2ZENCRFFTQXRJRWN6TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd0hoY05NakV3TXpFM01qQXpOekV3V2hjTk16WXdNekU1TURBd01EQXdXakIxTVVRd1FnWURWUVFERER0QmNIQnNaU0JYYjNKc1pIZHBaR1VnUkdWMlpXeHZjR1Z5SUZKbGJHRjBhVzl1Y3lCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEVMTUFrR0ExVUVDd3dDUnpZeEV6QVJCZ05WQkFvTUNrRndjR3hsSUVsdVl5NHhDekFKQmdOVkJBWVRBbFZUTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVic1FLQzk0UHJsV21aWG5YZ3R4emRWSkw4VDBTR1luZ0RSR3BuZ24zTjZQVDhKTUViN0ZEaTRiQm1QaENuWjMvc3E2UEYvY0djS1hXc0w1dk90ZVJoeUo0NXgzQVNQN2NPQithYW85MGZjcHhTdi9FWkZibmlBYk5nWkdoSWhwSW80SDZNSUgzTUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFBd0h3WURWUjBqQkJnd0ZvQVV1N0Rlb1ZnemlKcWtpcG5ldnIzcnI5ckxKS3N3UmdZSUt3WUJCUVVIQVFFRU9qQTRNRFlHQ0NzR0FRVUZCekFCaGlwb2RIUndPaTh2YjJOemNDNWhjSEJzWlM1amIyMHZiMk56Y0RBekxXRndjR3hsY205dmRHTmhaek13TndZRFZSMGZCREF3TGpBc29DcWdLSVltYUhSMGNEb3ZMMk55YkM1aGNIQnNaUzVqYjIwdllYQndiR1Z5YjI5MFkyRm5NeTVqY213d0hRWURWUjBPQkJZRUZEOHZsQ05SMDFESm1pZzk3YkI4NWMrbGtHS1pNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVFCZ29xaGtpRzkyTmtCZ0lCQkFJRkFEQUtCZ2dxaGtqT1BRUURBd05vQURCbEFqQkFYaFNxNUl5S29nTUNQdHc0OTBCYUI2NzdDYUVHSlh1ZlFCL0VxWkdkNkNTamlDdE9udU1UYlhWWG14eGN4ZmtDTVFEVFNQeGFyWlh2TnJreFUzVGtVTUkzM3l6dkZWVlJUNHd4V0pDOTk0T3NkY1o0K1JHTnNZRHlSNWdtZHIwbkRHZz0iLCJNSUlDUXpDQ0FjbWdBd0lCQWdJSUxjWDhpTkxGUzVVd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVUVBd3dTUVhCd2JHVWdVbTl2ZENCRFFTQXRJRWN6TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd0hoY05NVFF3TkRNd01UZ3hPVEEyV2hjTk16a3dORE13TVRneE9UQTJXakJuTVJzd0dRWURWUVFEREJKQmNIQnNaU0JTYjI5MElFTkJJQzBnUnpNeEpqQWtCZ05WQkFzTUhVRndjR3hsSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVFzd0NRWURWUVFHRXdKVlV6QjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkpqcEx6MUFjcVR0a3lKeWdSTWMzUkNWOGNXalRuSGNGQmJaRHVXbUJTcDNaSHRmVGpqVHV4eEV0WC8xSDdZeVlsM0o2WVJiVHpCUEVWb0EvVmhZREtYMUR5eE5CMGNUZGRxWGw1ZHZNVnp0SzUxN0lEdll1VlRaWHBta09sRUtNYU5DTUVBd0hRWURWUjBPQkJZRUZMdXczcUZZTTRpYXBJcVozcjY5NjYvYXl5U3JNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01Bb0dDQ3FHU000OUJBTURBMmdBTUdVQ01RQ0Q2Y0hFRmw0YVhUUVkyZTN2OUd3T0FFWkx1Tit5UmhIRkQvM21lb3locG12T3dnUFVuUFdUeG5TNGF0K3FJeFVDTUcxbWloREsxQTNVVDgyTlF6NjBpbU9sTTI3amJkb1h0MlFmeUZNbStZaGlkRGtMRjF2TFVhZ002QmdENTZLeUtBPT0iXX0.eyJ0cmFuc2FjdGlvbklkIjoiMzIwMDAxOTIwNDA2NDQwIiwib3JpZ2luYWxUcmFuc2FjdGlvbklkIjoiMzIwMDAxOTIwNDA2NDQwIiwiYnVuZGxlSWQiOiJhcHAubWlkYS5jb20iLCJwcm9kdWN0SWQiOiI4MTMiLCJwdXJjaGFzZURhdGUiOjE3MjI3NDY2NDUwMDAsIm9yaWdpbmFsUHVyY2hhc2VEYXRlIjoxNzIyNzQ2NjQ1MDAwLCJxdWFudGl0eSI6MSwidHlwZSI6Ik5vbi1Db25zdW1hYmxlIiwiaW5BcHBPd25lcnNoaXBUeXBlIjoiUFVSQ0hBU0VEIiwic2lnbmVkRGF0ZSI6MTcyMzY3MTMyNTc3OSwiZW52aXJvbm1lbnQiOiJQcm9kdWN0aW9uIiwidHJhbnNhY3Rpb25SZWFzb24iOiJQVVJDSEFTRSIsInN0b3JlZnJvbnQiOiJDSE4iLCJzdG9yZWZyb250SWQiOiIxNDM0NjUiLCJwcmljZSI6ODg4MDAwLCJjdXJyZW5jeSI6IkNOWSJ9.NRT_zC9H99-egs_Au_wZZU--gPlR6zfVv28hfB2f7cBOyKzE4HH-jey3IUV61kJuIQMNCtEgz4_19h2VZVWzPA","appAppleId":6475955565},
			 * "notificationUUID":"9c808de0-9b81-4012-bef6-c83d34715d71",
			 * "signedDate":1723671325811,"notificationType":"REFUND_DECLINED","version":"2.0"}
			 * 
			 */
			JSONObject verifyAndGet = AppStoreUtil.verifyAndGet(appStoreNotifyPayLoadDto.getSignedPayload());
			refund.setAppleData(verifyAndGet.toJSONString());
			refund.setRefundTime(new Date(verifyAndGet.getLong("signedDate")));
			refund.setNotificationType(verifyAndGet.getString("notificationType"));
			
			JSONObject data = verifyAndGet.getJSONObject("data");
			String signedTransactionInfo = data.getString("signedTransactionInfo");
			DecodedJWT decode = JWT.decode(signedTransactionInfo);
		    String decodeString = new String(Base64.getDecoder().decode(decode.getPayload()));
		    refund.setTransactionInfo(decodeString);
		    JSONObject parseObject = JSONObject.parseObject(decodeString);
			refund.setTransactionId(parseObject.getString("transactionId"));
		} catch (Exception e) {
			e.printStackTrace();
			refund.setExtend(e.getMessage());
		}
		userAppleRefundMapper.insert(refund);
		taskAsync.appleRefund(refund.getId());
		return "200";
	}
}
